package ext.tianma.upload;

import java.beans.PropertyVetoException;
import java.io.File;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Vector;

import org.apache.log4j.Logger;

import com.ptc.netmarkets.model.NmOid;
import com.ptc.windchill.enterprise.workflow.WfDataUtilitiesHelper;
import com.ptc.windchill.enterprise.workflow.WorkflowCommands;

import ext.com.iba.IBAUtil;
import ext.tianma.util.IbaAttributeUtil;
import ext.tianma.util.PropertiesUtil;
import ext.tianma.workflow.BomWorkFlowUtil;
import ext.tianma.workflow.WorkItemHelper;
import wt.access.AccessPermission;
import wt.access.AccessPermissionSet;
import wt.content.ApplicationData;
import wt.content.ContentHelper;
import wt.content.ContentHolder;
import wt.content.ContentItem;
import wt.doc.WTDocument;
import wt.fc.ObjectReference;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.PersistenceServerHelper;
import wt.fc.QueryResult;
import wt.fc.ReferenceFactory;
import wt.fc.WTObject;
import wt.httpgw.URLFactory;
import wt.inf.container.WTContainer;
import wt.inf.team.ContainerTeam;
import wt.inf.team.ContainerTeamHelper;
import wt.inf.team.ContainerTeamManaged;
import wt.lifecycle.LifeCycleHelper;
import wt.lifecycle.LifeCycleManaged;
import wt.lifecycle.State;
import wt.log4j.LogR;
import wt.org.DirectoryContextProvider;
import wt.org.GenericDirectoryContextProvider;
import wt.org.OrganizationServicesHelper;
import wt.org.WTGroup;
import wt.org.WTPrincipal;
import wt.org.WTPrincipalReference;
import wt.org.WTUser;
import wt.part.WTPart;
import wt.pdmlink.PDMLinkProduct;
import wt.project.Role;
import wt.query.QueryException;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.session.SessionHelper;
import wt.team.Team;
import wt.team.TeamManaged;
import wt.util.WTException;
import wt.util.WTPropertyVetoException;
import wt.util.WTRuntimeException;
import wt.workflow.WfException;
import wt.workflow.engine.WfActivity;
import wt.workflow.engine.WfBlock;
import wt.workflow.engine.WfContainer;
import wt.workflow.engine.WfProcess;
import wt.workflow.engine.WfVariable;
import wt.workflow.work.WfAssignedActivity;
import wt.workflow.work.WorkItem;

public class MyUtil {

	/**
	 * 获取流程主对象的Oid
	 * 
	 * @param pbo
	 * @return
	 * @throws WTException
	 */
	public static String getStr(ObjectReference self, Persistable pbo, int key) throws WTException {
		String str = "";
		String baseHref = new URLFactory().getBaseHREF();

		ReferenceFactory rf = new ReferenceFactory();
		WfProcess wfProcess = getWfProcess(self);
		String wid = rf.getReferenceString(wfProcess);

		if (pbo instanceof WTPart) {
			WTPart part = (WTPart) pbo;
			String oid = rf.getReferenceString(part);
			switch (key) {
			case 0:
				str = "<a href=\"Javascript:var processWindow = window.open('" + baseHref
						+ "netmarkets/jsp/upload/upload.jsp?oid=" + oid + "&wid=" + wid
						+ "&docKey=appDoc', '_blank', 'resizable=no,scrollbars=yes,menubar=no,toolbar=no,location=no,status=no');\">"
						+ "上传" + "</a>";
				break;

				
			case 1:
				str = "<a href=\"Javascript:var processWindow = window.open('" + baseHref
						+ "netmarkets/jsp/upload/upload2.jsp?oid=" + oid + "&wid=" + wid
						+ "&docKey=partDoc', '_blank', 'resizable=no,scrollbars=yes,menubar=no,toolbar=no,location=no,status=no');\">"
						+ "上传" + "</a>";
				break;
				
			case 2:
				str = "<a href=\"Javascript:var processWindow = window.open('" + baseHref
						+ "netmarkets/jsp/upload/upload3.jsp?oid=" + oid + "&wid=" + wid
						+ "&docKey=appDoc', '_blank', 'resizable=no,scrollbars=yes,menubar=no,toolbar=no,location=no,status=no');\">"
						+ "上传" + "</a>";
				break;

			case 3:
				str = "<a href=\"Javascript:var processWindow = window.open('" + baseHref
						+ "netmarkets/jsp/upload/upload4.jsp?oid=" + oid + "&wid=" + wid
						+ "&docKey=safeDoc', '_blank', 'resizable=no,scrollbars=yes,menubar=no,toolbar=no,location=no,status=no');\">"
						+ "上传" + "</a>";
				break;

			default:
				break;
			}

		}
		
		return str;

	}

	/*public static WfProcess getWfProcess(WfActivity wfAct) throws WTException {
		return wfAct.getParentProcess();
	}*/
	
	
	/**
	 * 文档上传非空校验
	 * @param self
	 * @throws WTException
	 */
	public static void judge1(ObjectReference self) throws WTException {
		WfProcess process = getWfProcess(self);
		WfVariable variable = process.getContext().getVariable("appDoc");
		Object value = variable.getValue();
		if(value==null) {
			throw new WTException("任务不能完成：上传文档不能为空");
		}
	}
	
	public static void judge2(ObjectReference self) throws WTException, RemoteException {
		String specialMonitor = "";
		WfProcess process = getWfProcess(self);
		WTObject pbo = WorkItemHelper.getPBO(process);
		if(pbo instanceof WTPart) {
			WTPart part = (WTPart)pbo;
			specialMonitor = (String)IBAUtil.getIBAValue(part, "specialMonitor");
		}
		WfVariable variable = process.getContext().getVariable("partDoc");
		Object value = variable.getValue();
		if("是".equals(specialMonitor) && value==null) {
			throw new WTException("任务不能完成：上传文档不能为空");
		}
	}

	private static Logger logger = LogR.getLogger(MyUtil.class.getName());

	/**
	 * className 完整类名 attribute 类中的属性 value 属性值
	 * @param className
	 * @param attribute
	 * @param value
	 * @return
	 * @throws WTException
	 */
	public static QueryResult getQueryResult(Class className, String attribute, String value) throws WTException {
		QueryResult qr = null;
		try {
			QuerySpec qs = new QuerySpec(className);
			SearchCondition sc = new SearchCondition(className, attribute, SearchCondition.EQUAL, value);
			qs.appendWhere(sc);
			qr = PersistenceHelper.manager.find(qs);

		} catch (Exception e) {

			logger.error("查询出错！请联系管理员！");

		}
		return qr;
	}

	/**
	 * 获取工作流任务节点
	 * @param process
	 * @return
	 * @throws WfException
	 * @throws WTException
	 */
	public static List<WorkItem> getWorkItem(WfProcess process) throws WfException, WTException {
		List<WorkItem> wi = new ArrayList<WorkItem>();
		try {
			wt.fc.ReferenceFactory rf = new wt.fc.ReferenceFactory();
			String processOid = rf.getReferenceString(process);
			NmOid oid = NmOid.newNmOid(processOid);
			QueryResult qr = WorkflowCommands.getRouteStatus(oid);// 分配了，没做的工作,有路由、计时器和工作任务等对象
			while (qr.hasMoreElements()) {
				Object object = qr.nextElement();
				if (object instanceof WorkItem) {
					wi.add((WorkItem) object);
				} 
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return wi;
	}

	/**
	 * 获取流程参与者
	 * @param wi
	 * @return
	 * @throws WTException
	 */
	public static List<WTUser> getUsers(WorkItem wi) throws WTException {
		List<WTUser> users = new ArrayList<WTUser>();
		String completedBy = wi.getCompletedBy();
		if (completedBy != null) {
			WTPrincipalReference prinReference = WfDataUtilitiesHelper.getUserPrinRef(completedBy);
			if (prinReference != null) {
				WTPrincipal prin = (WTPrincipal) prinReference.getObject();
				if (prin instanceof WTUser) {
					users.add((WTUser) prin);
				}
			}
		}
		return users;
	}

	/**
	 * 为流程节点的参与者赋权
	 * @param self
	 * @param document
	 * @param activeName
	 * @throws WTException
	 */
	public static void setAcess(ObjectReference self, WTDocument document, String activeName) throws WTException {
		WfProcess process = (WfProcess) getWfProcess(self);
		List<WTUser> users = getUser(process, activeName);
		WfVariable variable = process.getContext().getVariable("appDoc");
		for (int j = 0; j < users.size(); j++) {
			WTUser user = users.get(j);
			WTPrincipalReference prf = WTPrincipalReference.newWTPrincipalReference(user);
			AccessPermissionSet permissionSet = new AccessPermissionSet();
			permissionSet.add(AccessPermission.MODIFY);
			permissionSet.add(AccessPermission.MODIFY_CONTENT);

			if(document != null) {
				document = (WTDocument) wt.access.AccessControlHelper.manager.addPermission((wt.access.AdHocControlled) document, prf,
						wt.access.AccessPermission.DOWNLOAD, wt.access.AdHocAccessKey.WNC_ACCESS_CONTROL);
				PersistenceServerHelper.manager.update(document);
			}
			
		}

	}

	
	/**
	 * 获取当前节点的参与者
	 * @param process
	 * @param name
	 * @return
	 * @throws WfException
	 * @throws WTException
	 */
	public static List<WTUser> getUser(WfProcess process, String name) throws WTException {
			List<WTUser> userList = new ArrayList<WTUser>();
			Role role = Role.toRole("Assessor");
			if(role == null) {
				throw new WTException("系统不存在审核者角色！");
			}
			// 通过角色获取责任人
			Team team = (Team) process.getTeamId().getObject();
			WTPrincipalReference wtprincipalreference = null;
			Persistable persistable = null;
			WTUser wtuser = null;
			Enumeration enumPrin = team.getPrincipalTarget(role);
			while (enumPrin.hasMoreElements()) {
				wtprincipalreference = (WTPrincipalReference) enumPrin.nextElement();
				persistable = wtprincipalreference.getObject();
				if (persistable instanceof WTUser) {
					wtuser = (WTUser) persistable;
					userList.add(wtuser);
				}
			}
			return userList;
	}

	public static WfProcess getWfProcess(ObjectReference self) throws WTException {
		if (self == null) {
			return null;
		}
		Persistable persistable = self.getObject();
		if (persistable instanceof WfAssignedActivity) {
			return ((WfAssignedActivity) persistable).getParentProcess();
		} else if (persistable instanceof WfProcess) {
			return (WfProcess) persistable;
		}
		return null;
	}

	/**
	 * 获取下载链接中的cioids
	 * 
	 * @param doc
	 * @return
	 * @throws WTException
	 * @throws PropertyVetoException
	 */
	public static String getPrimaryId(WTDocument doc) throws WTException, PropertyVetoException {
		String cioids = "";
		if (doc != null) {
			ContentHolder contentholder = (ContentHolder) doc;
			contentholder = ContentHelper.service.getContents(contentholder);
			Vector v = ContentHelper.getContentListAll(contentholder);
			for (int j = 0; j < v.size(); j++) {
				ContentItem contentItem = (ContentItem) v.elementAt(j);
				if (contentItem.getRole().toString().equals("PRIMARY")) {
					ApplicationData appData = (ApplicationData) v.elementAt(j);
					ReferenceFactory ref = new wt.fc.ReferenceFactory();
					cioids = ref.getReferenceString(appData);
				}
			}
		}
		return cioids;
	}

	/**
	 * 获取产品列表
	 * 
	 * @return
	 * @throws WTException
	 */
	public static ArrayList<String> getContainnerList() throws WTException {
		ArrayList<String> wtcontains = new ArrayList<String>();
		WTContainer containner = null;
		QuerySpec qs = new QuerySpec(PDMLinkProduct.class);
		QueryResult qr = PersistenceHelper.manager.find(qs);
		while (qr.hasMoreElements()) {
			containner = (PDMLinkProduct) qr.nextElement();
			String containnerName = containner.getName();
			wtcontains.add(containnerName);
		}
		return wtcontains;
	}

	/**
	 * 获取要展示的产品库列表
	 * 
	 * @return
	 * @throws WTException
	 */
	public static ArrayList<String> removeDuplicate(ArrayList<String>  list) {  
		
	    HashSet<String> h = new HashSet<String>(list);   
	    list.clear();   
	    list.addAll(h);   
	    return list;   
	}
	
	
	
	
	/**
	 * 获取当前用户所在的容器
	 * @return
	 * @throws WTException
	 */
	public static ArrayList<String> getContainer() throws WTException{
		//通过容器获取团队，再获取团队所有的人，然后和当前用户遍历比较，得出用户所在的容器
		String curName = ((WTUser)SessionHelper.manager.getPrincipal()).getName();
		ArrayList<String> containnerList = getContainnerList();
		ArrayList<String> showCon = new ArrayList<String>();
		ArrayList<String> show = new ArrayList<String>();
		for(int i=0; i<containnerList.size(); i++){
			String name = containnerList.get(i);
			WTContainer container = getWTContainerByName(name);
			ContainerTeam containerteam = ContainerTeamHelper.service.getContainerTeam((ContainerTeamManaged) container);
			Vector roles = containerteam.getRoles();
	            for (int j = 0; j < roles.size(); j++) {
					
					Role role = (Role)roles.elementAt(j);
					ArrayList<?> principalReferenceList = containerteam.getAllPrincipalsForTarget(role);

			        for (Object obj : principalReferenceList) {
			            WTPrincipalReference wtPrincipalReference = (WTPrincipalReference) obj;
			            WTPrincipal principal = (WTPrincipal) wtPrincipalReference.getObject();
			            if (principal instanceof WTUser) {
			            	WTUser userTemp = (WTUser) principal;
							if (userTemp.getName().equals(curName)) {
								showCon.add(container.getName());
								show = removeDuplicate(showCon);
							}
			            } else if (principal instanceof WTGroup) {
			                WTGroup group = (WTGroup) principal;
			                List<WTUser> list = getUserFromGroup(group);
			                for(int k=0; k<list.size(); k++) {
			                	WTUser userTemp = list.get(k);
			                	if (userTemp.getName().equals(curName)) {
									showCon.add(container.getName());
									show = removeDuplicate(showCon);
								}
			                }
			            }
			        }
					
					
				}

		}
		return show;

	}
	
	/**
	 * 获取组下面的用户
	 * @param group
	 * @return
	 */
	public static List<WTUser> getUserFromGroup(WTGroup group) {
        List<WTUser> vector = new ArrayList<WTUser>();
        // WTGroup group;
        try {
            // group = OrganizationServicesHelper.manager.getGroup(strRole);
            if(group==null){
                return vector;
            }
            Enumeration<?> enu = group.members();
            while (enu.hasMoreElements()) {
                Object obj = enu.nextElement();

                if (obj instanceof WTUser) {
                    WTUser wtuser = (WTUser) obj;
                    vector.add(wtuser);
                }
            }
        } catch (WTException e) {
        	logger.error("getUserFromGroup",e);
        }

        return vector;
    }

	/**
	 * 根据库的名称，查询库
	 * 
	 * @param s
	 * @return
	 * @throws wt.query.QueryException
	 * @throws wt.util.WTException
	 */
	public static WTContainer getWTContainerByName(String s) throws QueryException, WTException {
		QuerySpec queryspec = new QuerySpec(WTContainer.class);
		queryspec.appendSearchCondition(
				new SearchCondition(WTContainer.class, WTContainer.NAME, SearchCondition.EQUAL, s));
		QueryResult queryresult = PersistenceHelper.manager.find(queryspec);
		WTContainer wtcontainer = null;
		while (queryresult.hasMoreElements()) {
			Object obj = queryresult.nextElement();
			if (obj instanceof WTContainer)
				wtcontainer = (WTContainer) obj;
		}
		return wtcontainer;

	}
	
	public static Persistable getObjectByOid(String oid)
			throws WTRuntimeException, WTException {
		ReferenceFactory rf = new ReferenceFactory();	
		return rf.getReference(oid).getObject();

	}
	
	
	/**
	 * 根据workItem的id获取对应的process
	 * @param oid
	 * @return
	 * @throws WTException
	 */
	public static  WfProcess GetWfProcess(String oid) throws WTException
	{	
		ReferenceFactory rf = new ReferenceFactory();
		WorkItem wi = (WorkItem) rf.getReference(oid).getObject();
		WfActivity wfAct = (WfActivity) wi.getSource().getObject();
		WfContainer wfcont = (WfContainer) wfAct.getParentProcessRef().getObject();
		WfProcess process = null;
		if (wfcont instanceof WfBlock) {
			WfBlock wfblock = (WfBlock)wfcont;
			process =wfblock.getParentProcess();
		} else {
			process = (WfProcess) wfcont;
		}
		return process;
		
	}
	
	/**
     * 设置对象生命周期状态
     *
     * @param obj 需要设置生命周期状态的对象
     * @param stateStr 被设置的生命周期状态；如果不存在该生命周期状态，则不设置
     * @return 被设置的对象
     * @throws WTException
     */
    public static LifeCycleManaged setLifeCycleState(LifeCycleManaged obj, String stateStr) throws WTException
    {
        State state = State.toState(stateStr);
        if (state.equals(obj.getLifeCycleState()))
            return obj;
        obj = LifeCycleHelper.service.setLifeCycleState(obj, state);

        return obj;
    }
    
    
    /***
	 * 根据用户名称获取user
	 * 
	 * @param name
	 * @return
	 */
	private static WTUser getUserByName(String name) {
		WTUser user = null;
		try {
			String[] defaultService = OrganizationServicesHelper.manager.getDirectoryServiceNames();
			DirectoryContextProvider dcp = OrganizationServicesHelper.manager
					.newDirectoryContextProvider(defaultService, new String[] { "subtree" });
			Enumeration eee = OrganizationServicesHelper.manager.findLikeUsers("name", name,
					new GenericDirectoryContextProvider(defaultService));
			if (eee.hasMoreElements())
				user = (WTUser) eee.nextElement();
		} catch (WTException wte) {
			wte.printStackTrace();
		}
		return user;
	}

	/**
	 * 给指定角色添加用户
	 * 
	 * @param self
	 * @param internal_value
	 * @param user
	 * @throws WTException 
	 * @throws RemoteException 
	 * @throws Exception
	 */
	public static void setRoleUser(ObjectReference self, WTPart part, String roleName, boolean b) throws WTException, RemoteException {
		String sqeUser = "codebase" + File.separator + "ext" + File.separator + "tianma"
				+ File.separator + "cfg" + File.separator + "TianmaPro.properties";
		PropertiesUtil ut = new PropertiesUtil(sqeUser);
		String specialMonitor = (String)IBAUtil.getIBAValue(part,"specialMonitor");
		System.out.println("specialMonitor===>>"+specialMonitor);
		String userName = "";
		if("是".equals(specialMonitor)) {
			userName = ut.getValueByKey("part.SQEUser");
		} else {
			//中文名称
			String partCName = IbaAttributeUtil.getAttributeValue(part, "partCName");
			String SQEUserN = partCName +".SQEUserN";
			userName = ut.getValueByKey(SQEUserN);
		}
		try {
				WTUser wtUser = getUserByName(userName);
				if (wtUser == null) {
					throw new WTException("系统中不存在用户名为'" + userName + "'的用户！");
				}
				addPrincipalToRole(self, roleName, wtUser, b);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	
	/**
	 * 给角色添加用户
	 * 
	 * @param self
	 * @param internal_value
	 * @param user
	 * @throws WTPropertyVetoException
	 * @throws WTException
	 */
	public static void addPrincipalToRole(ObjectReference self, String roleName, WTUser user, boolean b)
			throws WTPropertyVetoException, WTException {
		WfProcess process = BomWorkFlowUtil.getProcess(self);
		wt.team.Team team = null;
		try {
			team = getTeam(process);
		} catch (Exception ex) {
			ex.printStackTrace();
			throw new WTException(ex);
		}

		Role role = Role.toRole(roleName);
		if (b == true) {
			team.addPrincipal(role, user);
		} else {
			team.deletePrincipalTarget(role, user);
		}
		PersistenceHelper.manager.refresh(team);
	}

	/**
	 * 根据用户名得到用户
	 * 
	 * @param name
	 * @return
	 * @throws WTException
	 */
	public static WTUser getUserFromName(String name) throws WTException {
		Enumeration enumUser = OrganizationServicesHelper.manager.findUser(WTUser.NAME, name);
		WTUser user = null;
		if (enumUser.hasMoreElements())
			user = (WTUser) enumUser.nextElement();

		if (user == null) {
			enumUser = OrganizationServicesHelper.manager.findUser(WTUser.FULL_NAME, name);
			if (enumUser.hasMoreElements())
				user = (WTUser) enumUser.nextElement();
		}

		if (user == null) {
			throw new WTException("系统中不存在用户名为'" + name + "'的用户！");
		}

		return user;
	}
	
	/**
	 * 根据WfProcess对象，获得团队
	 * 
	 * @param process
	 * @return
	 * @throws Exception
	 */
	public static Team getTeam(WfProcess process) throws Exception {

		Team team = null;
		ReferenceFactory rf = new ReferenceFactory();
		String oid = rf.getReferenceString(process);
		WTObject wtobject = (WTObject) rf.getReference(oid).getObject();
		if (wtobject instanceof TeamManaged) {
			team = (Team) ((TeamManaged) wtobject).getTeamId().getObject();
		} else if (wtobject instanceof Team) {
			team = (Team) wtobject;
		}
		return team;
	}
}
